﻿namespace Zove.Runtime.Core.InferencingStrategy {

    /// <summary>
    /// Classic inferencing strategy
    /// </summary>
    public class ClassicInferencingStrategy : AbstractInferencingStrategy {

        /// <summary>
        /// Run the algorithm
        /// </summary>
        /// <param name="zoveObject">the model instance</param>
        public override void Infer(ZoveObject zoveObject) {
            bool eligible = false;
            bool updated = false;
            RuntimeFactor solved = null;

            do {
                updated = false;
                foreach (RuntimeFactor rf in zoveObject.Model.Factors) {
                    if (rf.Status != RuntimeFactorStatus.Unknown) {
                        continue;
                    }

                    foreach (RuntimeRule rr in rf.Rules) {
                        int count = 0;
                        bool done = true;
                        foreach (RuntimeFactor rrf in rr.Equation.Factors) {
                            if (rrf == rf) {
                                continue;
                            }

                            if (rrf.Status == RuntimeFactorStatus.Unknown) {
                                done = false;
                                break;
                            }

                            count++;
                        }
                        if (done) {
                            updated = true;

                            rf.Solve(rr);

                            SolvedFactor se = new SolvedFactor();
                            se.Strategy = this;
                            se.Factor = rf;
                            se.Rule = rr;

                            //this.Evaluate(se);
                            zoveObject.Queue[solved.Name] = se;
                        }
                    }
                }
            }
            while (updated);
        }
    }
}
